/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = tonglinkq_analysis.c                                          */
/*  NOTE      = TongLINK/Q协议解析                                            */
/*  DATE      = 2015/07/15 by wuwk                                            */
/******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>

#include "frsoap_parse.h"
#include "tonglinkq_core.h"
#include "tonglinkq_comm.h"

#define TLQ_INT                   0
#define TLQ_STRING             1

#define TLQ_MSG_BUF          0
#define TLQ_MSG_FILE          1

#define TLQ_HEAD_LEN         536
#define TLQ_MSGSIZE_MAX  2147483648
#define TLQ_LEN_M            1048576

#define TLQ_FML_HEAD_FLAG_CHAR	'~'	/* FML数据标志字符 */

#define TLQ_FML_SHORT 	0x00
#define TLQ_FML_LONG	0x20
#define TLQ_FML_CHAR  	0x40
#define TLQ_FML_FLOAT 	0x60
#define TLQ_FML_DOUBLE 0x80
#define TLQ_FML_STRING 	0xa0
#define TLQ_FML_CARRAY 0xc0
#define TLQ_FML_INT    	0xe0

#define TLQ_JMS_DATA_TYPE_TEXT          0x31
#define TLQ_JMS_DATA_TYPE_BYTE          0x32
#define TLQ_JMS_DATA_TYPE_MAP          0x33
#define TLQ_JMS_DATA_TYPE_STREAM          0x34
#define TLQ_JMS_DATA_TYPE_OBJECT          0x35

#define TLQ_TONG_MESSAGETYPE    "JMS_TONG_MessageType"
#define TLQ_TMQITOPIC_PUBQUE     "tmqiTopicPubQueueName"
#define TLQ_TMQIDEST_QUEUE         "tmqiDestinationName"

#define TLQ_MSG_TYPE_TEXT             "text"
#define TLQ_MSG_TYPE_OBJ             "binary"
#define TLQ_MSG_TYPE_MAP             "hashmap"
#define TLQ_MSG_TYPE_FML             "fml"
#define TLQ_MSG_TYPE_LIST             "list"
#define TLQ_MSG_TYPE_FILE             "file"

#define TLQ_MSG_FILE_INFO             "file.info"
#define TLQ_MSG_FILE_DATA             "file.data"

#define TLQ_MESSAGE_TYPE_TEXT            "text"
#define TLQ_MESSAGE_TYPE_BIN            "binary"
#define TLQ_MESSAGE_TYPE_MAP           "hashmap"

#define TLQ_DATA_TYPE_BOOL          "java.lang.Boolean"
#define TLQ_DATA_TYPE_CHAR          "java.lang.Character"
#define TLQ_DATA_TYPE_SHORT          "java.lang.Short"
#define TLQ_DATA_TYPE_INT          "java.lang.Integer"
#define TLQ_DATA_TYPE_LONG          "java.lang.Long"
#define TLQ_DATA_TYPE_FLOAT          "java.lang.Float"
#define TLQ_DATA_TYPE_DOUBLE          "java.lang.Double"
#define TLQ_DATA_TYPE_BYTE          "java.lang.Byte"


#define MQ_SUB                          APM_REPORT_KEY_SUB".mq"
#define MQ_SUB_TOPIC                      MQ_SUB".topic"

#define MQ_PUB                          APM_REPORT_KEY_PUB".mq"
#define MQ_PUB_QUE                      MQ_PUB".queue"
#define MQ_PUB_MQ_MSG             MQ_PUB".message"

#define MQ_REQUEST_QUE        APM_REPORT_KEY_REQ".mq.queue"

#define TLQ_REPORT_MQ                 "mq"
#define TLQ_REPORT_MQ_MSG             "mq.message"

#define MQ_PRIORITY_REQ           "request.mq.priority"
#define MQ_PRIORITY_RESP           "response.mq.priority"
#define MQ_PRIORITY_NOTIFY           "notify.mq.priority"

#define MQ_METHOD_REQ             "request.mq.method"

#define MQ_MESSAGE_TYPE             "mq.message.type"

#define MQ_MESSAGE_REQ           "request.mq.message"
#define MQ_MESSAGE_RESP           "response.mq.message"
#define MQ_MESSAGE_NOTIFY      "notify.mq.message"

int gi_version = 0;

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

FR_STATIC int __tonglinkq_analysis_jms_data(Frbyte_Packet *p_st_data
                                          , Frreport_body_data *p_st_body_data
                                          , unsigned int u32_data_len
                                          , int i_req_resp
                                          , int i_is_pub
                                          , int i_size);

/*******************************************************************************
*  FUNC     :  取得MsgId
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_data(数据)
            :  i_req_resp(request还是response)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_get_msgid(L7session_tonglinkq_private *p_st_private
                                  , Frbyte_Packet *p_st_data
                                  , int i_req_resp)
{
    Tonglinkq_frbyte_req *p_st_req = NULL;
    Tonglinkq_frbyte_resp *p_st_resp = NULL;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* 定位到MsgId */
    bytebuff_skip(p_st_data, 61);

    if (i_req_resp == TLQ_REQUEST)
    {
        p_st_req = p_st_private->p_st_req;
        if (p_st_req == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_st_req->msgid, TLQ_MSGIDLEN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        p_st_resp = p_st_private->p_st_resp;
        if (p_st_resp == NULL)
            return FR_FAIL;

        i_ret = bytebuff_get_bytes(p_st_data, p_st_resp->msgid, TLQ_MSGIDLEN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q数据头部解析
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
            :  i_req_resp(request还是response)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_head(Frreport_body_data *p_st_body_data
                                      , Tonglinkq_L7session *p_st_L7session
                                      , Frbyte_Packet *p_st_data
                                      , int i_req_resp)
{
    char arr_tmp[TLQ_NAMELEN+2];
    uint16_t u16_len = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL || p_st_L7session == NULL)
        return FR_FAIL;

    /* 定位到数据长度 */
    bytebuff_skip(p_st_data, 6);

    if (i_req_resp == TLQ_REQUEST)
    {
        /* Len */
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 本地节点名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 队列控制单元名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 发送队列名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 被连接节点的IP */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        /* 没有队列控制单元名 */
        bytebuff_skip(p_st_data, TLQ_NAMELEN+1);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 目的队列名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);
        if (*arr_tmp != '\0')
        {
            /* 添加到session信息 */
            if (p_st_L7session->p_queue == NULL)
            {
                p_st_L7session->p_queue = frstrdup(arr_tmp);
                if (p_st_L7session->p_queue == NULL)
                    return FR_FAIL;
            }
        }
    }
    else
    {
        /* Len */
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        /* 被连接节点的IP */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        /* 没有队列控制单元名 */
        bytebuff_skip(p_st_data, TLQ_NAMELEN+1);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 目的队列名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        if (*arr_tmp != '\0')
        {
            /* 添加到session信息 */
            if (p_st_L7session->p_queue == NULL)
            {
                p_st_L7session->p_queue = frstrdup(arr_tmp);
                if (p_st_L7session->p_queue == NULL)
                    return FR_FAIL;
            }
        }

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 本地节点名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        /* 队列控制单元名 */
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, TLQ_NAMELEN+1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        frrtrim(arr_tmp);

        bytebuff_skip(p_st_data, TLQ_NAMELEN+1);
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q消息数据解析(FML)
*  ARGS     :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_fml(Frreport_body_data *p_st_body_data
                                     , Frbyte_Packet *p_st_data
                                     , int i_req_resp)
{
    unsigned char arr_tmp[5];
    char arr_key[64];
    char arr_msgtype[64];
    char arr_value[64];
    char *p_value = NULL;
    char *p_data = NULL;
    uint8_t u8_char = 0;
    uint16_t u16_len = 0;
    uint32_t u32_len = 0;
    uint64_t u64_len = 0;
    float f_value = 0.0;
    union int32_float_bits u_32bits;
    double db_value = 0.0;
    union int64_double_bits u_64bits;
    int i_buffsize = 0;
    int i_usedsize = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* ~(\x7E) */
    bytebuff_skip(p_st_data, 1);

    /* fml数据长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (u32_len > TLQ_LEN_M*100)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 28);

    if (i_req_resp == TLQ_REQUEST)
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "request.%s", MQ_MESSAGE_TYPE);
        snprintf(arr_key, sizeof(arr_key), "request.%s.%s", TLQ_REPORT_MQ_MSG, TLQ_MSG_TYPE_LIST);
    }
    else
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "response.%s.1", MQ_MESSAGE_TYPE);
        snprintf(arr_key, sizeof(arr_key), "request.%s.%s.1", TLQ_REPORT_MQ_MSG, TLQ_MSG_TYPE_LIST);
    }

    /* message.type */
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_msgtype, TLQ_MSG_TYPE_FML);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_value = (char *)frmalloc(u32_len + 1);
    if (p_value == NULL)
        return FR_FAIL;
    memset(p_value, 0x00, u32_len + 1);

    i_buffsize = u32_len + 1;
    strcpy(p_value, "[");
    i_usedsize = 1;

    while (bytebuff_remaining(p_st_data) >= 4)
    {
        memset((char *)arr_tmp, 0x00, sizeof(arr_tmp));
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 4);
        if (i_ret == FR_FAIL)
        {
            frfree(p_value);
            return FR_FAIL;
        }
        if (arr_tmp[2] == 0 && arr_tmp[3] == 0)
            continue;

        switch (arr_tmp[2])
        {
            case TLQ_FML_SHORT:
                i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }
                snprintf(arr_value, sizeof(arr_value), "%d", u16_len);

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%s,", arr_value);
                i_usedsize += (strlen(arr_value) + 1);

                break;
            case TLQ_FML_LONG:
                i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                snprintf(arr_value, sizeof(arr_value), "%ld", u64_len);

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%s,", arr_value);
                i_usedsize += (strlen(arr_value) + 1);

                break;
            case TLQ_FML_CHAR:
                i_ret = bytebuff_get_char(p_st_data, &u8_char);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%c,", u8_char);
                i_usedsize += 2;

                break;
            case TLQ_FML_FLOAT:
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                u_32bits.int_bits = u32_len;
                f_value = u_32bits.float_bits;

                snprintf(arr_value, sizeof(arr_value), "%f", f_value);

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%s,", arr_value);
                i_usedsize += (strlen(arr_value) + 1);

                break;
            case TLQ_FML_DOUBLE:
                i_ret = bytebuff_get_long(p_st_data, 8, &u64_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                u_64bits.int_bits = u64_len;
                db_value = u_64bits.double_bits;

                snprintf(arr_value, sizeof(arr_value), "%lf", db_value);

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%s,", arr_value);
                i_usedsize += (strlen(arr_value) + 1);

                break;
            case TLQ_FML_STRING:
            case TLQ_FML_CARRAY:
                /* 长度 */
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                if ((int)u32_len > bytebuff_remaining(p_st_data))
                    return FR_FAIL;

                p_data = (char *)frmalloc(u32_len + 1);
                if (p_data == NULL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }
                memset(p_data, 0x00, u32_len + 1);

                i_ret = bytebuff_get_bytes(p_st_data, p_data, u32_len);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    frfree(p_data);
                    return FR_FAIL;
                }

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "\"%s\",", p_data);
                i_usedsize += (strlen(p_data) + 3);
                frfree(p_data);

                break;
            case TLQ_FML_INT:
                i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
                if (i_ret == FR_FAIL)
                {
                    frfree(p_value);
                    return FR_FAIL;
                }

                snprintf(arr_value, sizeof(arr_value), "%d", u32_len);

                snprintf(p_value+i_usedsize, i_buffsize-i_usedsize, "%s,", arr_value);
                i_usedsize += (strlen(arr_value) + 1);

                break;
            default:
                return FR_FAIL;
        }
    }

    p_value[i_usedsize-1] = ']';

    /* 数据上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_value);
    if (i_ret == FR_FAIL)
    {
        frfree(p_value);
        return FR_FAIL;
    }

    frfree(p_value);

    if (bytebuff_remaining(p_st_data) != 0)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  消息自定义属性跳过
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_property_skip(Frbyte_Packet *p_st_data)
{
    char arr_type[2];
    uint32_t u32_len = 0;
    int i_ret = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    memset(arr_type, 0x00, sizeof(arr_type));
    /* 自定义名称长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if ((int)u32_len > bytebuff_remaining(p_st_data))
        return FR_FAIL;

    bytebuff_skip(p_st_data, u32_len);

    /* 自定义类型 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_type, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 自定义内容长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (*arr_type == 'C')
    {
        if ((int)(u32_len-1) > bytebuff_remaining(p_st_data))
            return FR_FAIL;

        bytebuff_skip(p_st_data, u32_len-1);
    }
    else
    {
        if ((int)u32_len > bytebuff_remaining(p_st_data))
            return FR_FAIL;

        bytebuff_skip(p_st_data, u32_len);
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  取得消息内容
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_get_msg_data(Frreport_body_data *p_st_body_data
                                     , Frbyte_Packet *p_st_data
                                     , unsigned int ui_data_len)
{
    uint32_t u32_len = 0;
    uint32_t u32_property_num = 0;
    char *p_data = NULL;
    char arr_key[64];
    int i_loop = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 8);
    /* 长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 剩余长度不足 */
    if (bytebuff_remaining(p_st_data) < (int)u32_len)
        return FR_FAIL;

    /* 属性个数 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_property_num, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < (int)u32_property_num)
        return FR_FAIL;

    for (; i_loop < (int)u32_property_num; i_loop++)
    {
        i_ret = __tonglinkq_property_skip(p_st_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    /* 取消息内容 */
    p_data = (char *)frmalloc(ui_data_len+1);
    if (p_data == NULL)
        return FR_FAIL;
    memset(p_data, 0x00, ui_data_len+1);
    i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_data_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    memset(arr_key, 0x00, sizeof(arr_key));
    strcpy(arr_key, "request.");
    strcat(arr_key, TLQ_REPORT_MQ_MSG);
    i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, arr_key, p_data);
    frfree(p_data);

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q PUB数据解析
*  ARGS     :  :  p_st_body_data(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_pub(Frreport_body_data *p_st_body_data
                                     , Tonglinkq_L7session *p_st_L7session
                                     , Frbyte_Packet *p_st_data
                                     , unsigned int ui_data_len)
{
    char arr_topic[49];
    char arr_title[64];
    char arr_tlq[5];
    char arr_msgtype[64];
    char *p_data = NULL;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_L7session == NULL || p_st_data == NULL)
        return FR_FAIL;

    memset(arr_topic, 0x00, sizeof(arr_topic));

    bytebuff_skip(p_st_data, 64);
    memset(arr_tlq, 0x00, sizeof(arr_tlq));
    /* 是否以TLQ开头 */
    i_ret = bytebuff_peek_bytes(p_st_data, arr_tlq, 4);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* method上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (strncmp(arr_tlq+1, "TLQ", 3) == 0)
    {
        i_ret =  __tonglinkq_analysis_jms_data(p_st_data, p_st_body_data, ui_data_len, TLQ_REQUEST, TLQ_MSG_PUB, 0);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        snprintf(arr_msgtype, sizeof(arr_msgtype), "request.%s", MQ_MESSAGE_TYPE);
        /* message.type */
        if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, TLQ_MSG_TYPE_TEXT) == FR_FAIL)
            return FR_FAIL;

        /* 取得的长度大于剩余数据包长度 */
        if ((int)ui_data_len > bytebuff_remaining(p_st_data))
            return FR_FAIL;

        p_data = (char *)frmalloc(ui_data_len + 1);
        if (p_data == NULL)
            return FR_FAIL;

        memset(p_data, 0x00, ui_data_len + 1);
        /* 消息数据 */
        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_data_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }

//        snprintf(arr_key, sizeof(arr_key), "%s.1", MQ_PUB_MQ_MSG);
        /* 消息上报 */
        i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, MQ_MESSAGE_REQ, p_data);
        frfree(p_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    bytebuff_skip(p_st_data, 50);

    /* 主题名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_topic, 48);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_topic);

    /* 设置title */
    snprintf(arr_title, sizeof(arr_title), "PUT %s", arr_topic);
//    snprintf(arr_title, sizeof(arr_title), "PUB %s", arr_topic);
//    i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_TRANS_TITLE, arr_title);
//    if (i_ret == FR_FAIL)
//        return FR_FAIL;

    if (p_st_L7session->p_title)
        frfree(p_st_L7session->p_title);
    p_st_L7session->p_title = frstrdup(arr_title);
    if (p_st_L7session->p_title == NULL)
        return FR_FAIL;

    /* publish.mq.queue上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUE, arr_topic);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (p_st_L7session->p_queue != NULL)
        frfree(p_st_L7session->p_queue);

    p_st_L7session->p_queue = frstrdup(arr_topic);
    if (p_st_L7session->p_queue == NULL)
        return FR_FAIL;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q SUB数据解析
*  ARGS     :  :  p_st_body_data(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_sub(Frreport_body_data *p_st_body_data
                                     , Tonglinkq_L7session *p_st_L7session
                                     , Frbyte_Packet *p_st_data)
{
    char arr_title[64];
    char *p_topic = NULL;
    uint16_t u16_topic_len = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_L7session == NULL || p_st_data == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 12);

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_topic_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 取得的长度大于剩余数据包长度 */
    if (u16_topic_len > bytebuff_remaining(p_st_data))
        return FR_FAIL;

    p_topic = (char *)frmalloc(u16_topic_len + 1);
    if (p_topic == NULL)
        return FR_FAIL;

    memset(p_topic, 0x00, u16_topic_len+1);
    /* 主题名 */
    i_ret = bytebuff_get_bytes(p_st_data, p_topic, u16_topic_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_topic);
        return FR_FAIL;
    }

    /* 设置title */
    snprintf(arr_title, sizeof(arr_title), "SUB %s", p_topic);

    if (p_st_L7session->p_title)
        frfree(p_st_L7session->p_title);
    p_st_L7session->p_title = frstrdup(arr_title);
    if (p_st_L7session->p_title == NULL)
    {
        frfree(p_topic);
        return FR_FAIL;
    }

    /* subscription.mq.queue上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_SUB_TOPIC, p_topic);
    if (i_ret == FR_FAIL)
    {
        frfree(p_topic);
        return FR_FAIL;
    }

    if (p_st_L7session->p_queue != NULL)
        frfree(p_st_L7session->p_queue);
    p_st_L7session->p_queue = frstrdup(p_topic);
    if (p_st_L7session->p_queue == NULL)
    {
        frfree(p_topic);
        return FR_FAIL;
    }

    frfree(p_topic);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q消息数据解析(Buffer)
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_buffer(L7session_tonglinkq_private *p_st_private
                                        , Frreport_body_data *p_st_body_data
                                        , Frbyte_Packet *p_st_data
                                        , int *i_need_report)
{
    char *p_data = NULL;
    char arr_priority[2];
    char arr_queue[50];
    char arr_title[64];
    char arr_msgtype[64];
    char arr_size[64];
    Tonglinkq_frbyte_req *p_st_req = NULL;
    Tonglinkq_L7session *p_st_L7_session = NULL;
    uint32_t u32_len = 0;
    unsigned int ui_left_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_req == NULL
        || p_st_private->p_st_L7_session == NULL
        || p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_req = p_st_private->p_st_req;
    p_st_L7_session = p_st_private->p_st_L7_session;
    bytebuff_skip(p_st_data, 66);
    /* 消息长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 支持消息最大长度2G */
    if (u32_len > TLQ_MSGSIZE_MAX)
        return FR_FAIL;

    /* 消息优先级 */
    bytebuff_skip(p_st_data, 4);

    memset(arr_priority, 0x00, sizeof(arr_priority));
    i_ret = bytebuff_get_bytes(p_st_data, arr_priority, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 消息长度为0 */
//    if (u32_len == 0)
//    {
//        snprintf(arr_key, sizeof(arr_key), "%s.1", MQ_MESSAGE_REQ);
//        if (frreport_body_l7_add_str(p_st_body_data, arr_key, "") == FR_FAIL)
//            return FR_FAIL;
//        *i_need_report = TLQ_YES;
//        return FR_SUCC;
//    }

    bytebuff_skip(p_st_data, 109);

    memset(arr_queue, 0x00, sizeof(arr_queue));
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, 49);
    if (i_ret == FR_FAIL)
        return FR_FAIL;
    frrtrim(arr_queue);
    /* PUB/SUB */
    if (*arr_queue != '\0')
    {
        bytebuff_skip(p_st_data, 81);

        /* 消息内容长度 */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (u32_len > TLQ_LEN_M*100)
            return FR_FAIL;

        if (u32_len != 0)
        {
//            snprintf(arr_key, sizeof(arr_key), "%s.1", MQ_PRIORITY_PUB);
            /* 优先级 */
            i_ret = frreport_body_l7_add_int(p_st_body_data, MQ_PRIORITY_REQ, *arr_priority);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            /* queue */
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_TOPIC, arr_queue);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            p_st_private->i_istopic = TLQ_YES;
            i_ret = __tonglinkq_analysis_pub(p_st_body_data, p_st_private->p_st_L7_session, p_st_data, u32_len);
//            p_st_req->i_pubsub_flag = TLQ_MSG_PUB;
        }
        else
            *i_need_report = TLQ_NO;
        return i_ret;
    }

    i_ret = frreport_body_l7_add_int(p_st_body_data, MQ_PRIORITY_REQ, *arr_priority);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 到数据开始 */
    bytebuff_skip(p_st_data, 149);
    ui_left_len = bytebuff_remaining(p_st_data);
    /* 消息内容不完整，后面还有数据 */
    if (u32_len > ui_left_len)
    {
        p_st_req->ui_msg_len = u32_len;
        p_st_req->ui_msg_left_len = u32_len - ui_left_len;
        /* 创建消息buffer */
        p_st_req->p_st_msg = bytebuff_creat();
        if (p_st_req->p_st_msg == NULL)
            return FR_FAIL;

        p_data = (char *)frmalloc(ui_left_len + 1);
        if (p_data == NULL)
        {
            bytebuff_free(&p_st_req->p_st_msg);
            return FR_FAIL;
        }

        memset(p_data, 0x00, ui_left_len + 1);
        /* 消息内容 */
        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_left_len);
        if (i_ret == FR_FAIL)
        {
            bytebuff_free(&p_st_req->p_st_msg);
            frfree(p_data);
            return FR_FAIL;
        }
        frrtrim(p_data);

        i_ret = bytebuff_add(p_st_req->p_st_msg, p_data, ui_left_len);
        frfree(p_data);
        if (i_ret != FR_SUCC)
        {
            bytebuff_free(&p_st_req->p_st_msg);
            return FR_FAIL;
        }
        return APM_L7_ANALYZE_TODO;
    }
    else
    {
        /* title上报 */
        if (p_st_L7_session->p_queue != NULL)
        {
            /* queue */
            i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUEUE, p_st_L7_session->p_queue);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            memset(arr_title, 0x00, sizeof(arr_title));
            snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_L7_session->p_queue);
//            i_ret = frreport_body_l7_add_str(p_st_body_data, APM_REPORT_KEY_TRANS_TITLE, arr_title);
//            if (i_ret == FR_FAIL)
//                return FR_FAIL;

            if (p_st_L7_session->p_title)
                frfree(p_st_L7_session->p_title);
            p_st_L7_session->p_title = frstrdup(arr_title);
            if (p_st_L7_session->p_title == NULL)
                return FR_FAIL;
        }

        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (u32_len == 0)
        {
            snprintf(arr_msgtype, sizeof(arr_msgtype), "request.%s", MQ_MESSAGE_TYPE);
            // message.type
            if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, TLQ_MSG_TYPE_TEXT) == FR_FAIL)
                return FR_FAIL;

            snprintf(arr_size, sizeof(arr_size), "request.%s", MQ_MESSAGE_SIZE);
            // 消息个数上报
            i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, 1);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            if (frreport_body_l7_add_str(p_st_body_data, MQ_MESSAGE_REQ, "") == FR_FAIL)
                return FR_FAIL;
            *i_need_report = TLQ_YES;
            return FR_SUCC;
        }

        /* 数据长度大于上报上限, 该数据内容不上报 */
        if (u32_len > APM_REPORT_MQ_MAX)
            return FR_SUCC;

        p_data = (char *)frmalloc(u32_len + 1);
        if (p_data == NULL)
            return FR_FAIL;

        memset(p_data, 0x00, u32_len + 1);
        /* 消息内容 */
        i_ret = bytebuff_peek_bytes(p_st_data, p_data, u32_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
        frrtrim(p_data);

        /* FML数据开头位判断 */
        if (*p_data == TLQ_FML_HEAD_FLAG_CHAR)
            i_ret = __tonglinkq_analysis_fml(p_st_body_data, p_st_data, TLQ_REQUEST);
        else if (*p_data == '\0' && strncmp(p_data+1, "TLQ", 3) == 0)
            i_ret = __tonglinkq_get_msg_data(p_st_body_data, p_st_data, u32_len);
        else
        {
            snprintf(arr_msgtype, sizeof(arr_msgtype), "request.%s", MQ_MESSAGE_TYPE);
            // message.type
            if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, TLQ_MSG_TYPE_TEXT) == FR_FAIL)
                return FR_FAIL;

            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, MQ_MESSAGE_REQ, p_data);
        }

        frfree(p_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q消息数据解析(File)
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_file(L7session_tonglinkq_private *p_st_private
                                      , Frreport_body_data *p_st_body_data
                                      , Frbyte_Packet *p_st_data)
{
    Tonglinkq_L7session *p_st_L7_session = NULL;
    char *p_data = NULL;
    char *p_filename = NULL;
    char arr_msgtype_key[64];
    char arr_key[64];
    char arr_title[64];
    uint32_t u32_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_L7_session = p_st_private->p_st_L7_session;
    if (p_st_L7_session == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 66);
    /* 消息内容长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* FILE 消息消息长度不能超过512个字节，消息长度必须大于0 */
    if (u32_len == 0 || u32_len > TLQ_FILEMSG_MAX)
        return FR_FAIL;

    if (p_st_L7_session->p_queue != NULL)
    {
        memset(arr_title, 0x00, sizeof(arr_title));
        snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_L7_session->p_queue);

        if (p_st_L7_session->p_title)
            frfree(p_st_L7_session->p_title);
        p_st_L7_session->p_title = frstrdup(arr_title);
        if (p_st_L7_session->p_title == NULL)
            return FR_FAIL;

        /* queue */
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUE, p_st_L7_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    /* method */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(arr_msgtype_key, 0x00, sizeof(arr_msgtype_key));
    snprintf(arr_msgtype_key, sizeof(arr_msgtype_key), "request.%s", MQ_MESSAGE_TYPE);
    /* 消息类型上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_msgtype_key, TLQ_MSG_TYPE_FILE);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 312);

    p_data = (char *)frmalloc(u32_len + 1);
    if (p_data == NULL)
        return FR_FAIL;

    memset(p_data, 0x00, u32_len + 1);
    /* 消息内容(文件摘要) */
    i_ret = bytebuff_get_bytes(p_st_data, p_data, u32_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }
    frrtrim(p_data);

    p_filename = strtok(p_data, " ");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(arr_key, 0x00, sizeof(arr_key));
    snprintf(arr_key, sizeof(arr_key), "%s.%s", MQ_MESSAGE_REQ, TLQ_MSG_FILE_INFO);
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_filename);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    memset(p_st_private->file_name, 0x00, sizeof(p_st_private->file_name));
    memcpy(p_st_private->file_name, p_data, strlen(p_data));
    frfree(p_data);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q消息数据解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_msginfo(L7session_tonglinkq_private *p_st_private
                                         , Frreport_body_data *p_st_body_data
                                         , Frbyte_Packet *p_st_data
                                         , int *i_need_report)
{
    char *p_data = NULL;
    Tonglinkq_frbyte_req *p_st_req = NULL;
    Tonglinkq_L7session *p_st_session = NULL;
    char arr_server[64];
    char arr_title[64];
    uint16_t u16_len = 0;
    unsigned int ui_msg_len = 0;
    unsigned int ui_get_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_req == NULL
        || p_st_private->p_st_L7_session == NULL
        || p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    p_st_session = p_st_private->p_st_L7_session;

    p_st_req = p_st_private->p_st_req;
    /* 本次数据包是上次未完的消息内容 */
    if (p_st_req->p_st_msg != NULL)
    {
        ui_msg_len = bytebuff_remaining(p_st_data);
        ui_get_len = ui_msg_len > p_st_req->ui_msg_left_len? p_st_req->ui_msg_left_len: ui_msg_len;

        p_data = (char *)frmalloc(ui_get_len + 1);
        if (p_data == NULL)
            return FR_FAIL;

        memset(p_data, 0x00, ui_get_len + 1);
        /* 取得本次消息内容 */
        i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_get_len);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
        frrtrim(p_data);

        i_ret = bytebuff_add(p_st_req->p_st_msg, p_data, ui_get_len);
        frfree(p_data);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        /* 本次数据长度够 */
        if (p_st_req->ui_msg_left_len <= ui_msg_len)
        {
            p_data = (char *)frmalloc(p_st_req->ui_msg_len + 1);
            if (p_data == NULL)
                return FR_FAIL;

            memset(p_data, 0x00, p_st_req->ui_msg_len + 1);
            /* 取得完整的消息内容 */
            i_ret = bytebuff_peek_bytes(p_st_req->p_st_msg, p_data, p_st_req->ui_msg_len);
            if (i_ret == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }
            frrtrim(p_data);

            /* FML数据开头位判断 */
            if (*p_data == TLQ_FML_HEAD_FLAG_CHAR)
            {
                /* title上报 */
                if (p_st_session->p_queue != NULL)
                {
                    memset(arr_title, 0x00, sizeof(arr_title));
                    snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_session->p_queue);

                    if (p_st_session->p_title)
                        frfree(p_st_session->p_title);
                    p_st_session->p_title = frstrdup(arr_title);
                    if (p_st_session->p_title == NULL)
                    {
                        frfree(p_data);
                        return FR_FAIL;
                    }

                    /* queue */
                    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUE, p_st_session->p_queue);
                    if (i_ret == FR_FAIL)
                        return FR_FAIL;

                    /* method */
                    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
                    if (i_ret == FR_FAIL)
                        return FR_FAIL;
                }
                i_ret = __tonglinkq_analysis_fml(p_st_body_data, p_st_req->p_st_msg, TLQ_REQUEST);
            }
            else
                i_ret = tonglinkq_add_frlist_string(p_st_body_data, (char *)"message", p_data, TLQ_REQUEST);

            frfree(p_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            bytebuff_free(&p_st_req->p_st_msg);
            return FR_SUCC;
        }
        else
        {
            p_st_req->ui_msg_left_len -= ui_msg_len;
            return APM_L7_ANALYZE_TODO;
        }
    }

    /* 版本号 */
    i_ret = bytebuff_get_short(p_st_data, 1, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (gi_version == 0)
        gi_version = u16_len;

    /* 添加服务名到session */
    if (p_st_session->p_server == NULL)
    {
        memset(arr_server, 0x00, sizeof(arr_server));
        strcpy(arr_server, "tonglinkq");
        p_st_session->p_server = frstrdup(arr_server);
        if (p_st_session->p_server == NULL)
            return FR_FAIL;
    }

    /* 消息类型 */
    i_ret = bytebuff_get_short(p_st_data, 1, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (u16_len == TLQ_MSG_BUF)
        i_ret = __tonglinkq_analysis_buffer(p_st_private, p_st_body_data, p_st_data, i_need_report);
    else if (u16_len == TLQ_MSG_FILE)
        i_ret = __tonglinkq_analysis_file(p_st_private, p_st_body_data, p_st_data);
    else
        return FR_SUCC;

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q文件传输的文件内容数据包
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_lst_header(上报链表)
            :  p_st_data(数据)
*  RTN      :  FR_FAIL                   失败
*           :  FR_SUCC                   成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_file_data(L7session_tonglinkq_private *p_st_private
                                           , Frreport_body_data *p_st_body_data
                                           , Frbyte_Packet *p_st_data)
{
    Tonglinkq_L7session *p_st_L7_session = NULL;
    char arr_key[64];
    char arr_title[64];
    char *p_data = NULL;
    uint16_t u16_len = 0;
    int i_data_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_body_data == NULL || p_st_data == NULL)
        return FR_FAIL;

    /* 定位到数据长度 */
    bytebuff_skip(p_st_data, 6);

    memset(arr_title, 0x00, sizeof(arr_title));
    p_st_L7_session = p_st_private->p_st_L7_session;
    if (p_st_L7_session == NULL)
        return FR_FAIL;

    /* title上报 */
    if (p_st_L7_session->p_queue != NULL)
    {
        memset(arr_title, 0x00, sizeof(arr_title));
        snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_L7_session->p_queue);

        if (p_st_L7_session->p_title)
            frfree(p_st_L7_session->p_title);
        p_st_L7_session->p_title = frstrdup(arr_title);
        if (p_st_L7_session->p_title == NULL)
            return FR_FAIL;

        /* queue */
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUE, p_st_L7_session->p_queue);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    /* method */
    i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 文件名 */
    memset(arr_key, 0x00, sizeof(arr_key));
    snprintf(arr_key, sizeof(arr_key), "%s.%s", MQ_MESSAGE_REQ, TLQ_MSG_FILE_INFO);
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_st_private->file_name);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(p_st_private->file_name, 0x00, sizeof(p_st_private->file_name));

    /* 文件内容长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 长度超过最大 */
    if (u16_len > TLQ_LEN_M*100 || u16_len < TLQ_HEAD_LEN)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < u16_len-10)
        return APM_L7_ANALYZE_TODO;

    i_data_len = u16_len - TLQ_HEAD_LEN;

    /* file.len */
    snprintf(arr_key, sizeof(arr_key), "%s.%s.len", MQ_MESSAGE_REQ, TLQ_MSG_TYPE_FILE);
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_key, i_data_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, TLQ_HEAD_LEN-10);
    p_data = (char *)frmalloc(i_data_len + 1);
    if (p_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_st_data, p_data, i_data_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    /* 判断是否是xml数据 */
    if (frxml_detect(p_data, i_data_len) == FR_SUCC)
    {
        /* file.data */
        snprintf(arr_key, sizeof(arr_key), "%s.%s", MQ_MESSAGE_REQ, TLQ_MSG_FILE_DATA);
        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_data);
        if (i_ret == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }
    frfree(p_data);
//    bytebuff_skip(p_st_data, TLQ_HEAD_LEN-8+i_data_len);
    p_st_private->p_st_req->i_file_flag = 0;
    p_st_private->p_st_req->i_responserequired = 1;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q 取得MAP消息的value并上报(string以外)
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_map_getvalue(Frreport_body_data *p_st_body_data
                                              , Frbyte_Packet *p_st_data
                                              , char *p_key)
{
    char *p_type = NULL;
    uint8_t u8_type_len = 0;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_data == NULL  || p_key == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 2);

    /* 取得类型的长度 */
    i_ret = bytebuff_get_char(p_st_data, &u8_type_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    p_type = (char *)frmalloc(u8_type_len + 1);
    if (p_type == NULL)
        return FR_FAIL;
    memset(p_type, 0x00, u8_type_len + 1);

    /* 取得类型 */
    i_ret = bytebuff_get_bytes(p_st_data, p_type, u8_type_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_type);
        return FR_FAIL;
    }

    /* "value"后 */
    bytebuff_skip(p_st_data, 21);

    if (strcmp(p_type, TLQ_DATA_TYPE_BOOL) == 0)
    {
        i_ret = tonglinkq_get_map_boolean(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_CHAR) == 0)
    {
        i_ret = tonglinkq_get_map_char(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_SHORT) == 0)
    {
        i_ret = tonglinkq_get_map_short(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_INT) == 0)
    {
        i_ret = tonglinkq_get_map_int(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_LONG) == 0)
    {
        i_ret = tonglinkq_get_map_long(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_FLOAT) == 0)
    {
        i_ret = tonglinkq_get_map_float(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_DOUBLE) == 0)
    {
        i_ret = tonglinkq_get_map_double(p_st_body_data, p_st_data, p_key);
    }
    else if (strcmp(p_type, TLQ_DATA_TYPE_BYTE) == 0)
    {
        i_ret = tonglinkq_get_map_byte(p_st_body_data, p_st_data, p_key);
    }

    frfree(p_type);

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q MAP消息解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_map(Frbyte_Packet *p_st_data
                                     , Frreport_body_data *p_st_body_data
                                     , char *p_key)
{
    char *p_map_key = NULL;
    char *p_map_value = NULL;
    char arr_key[64];
    uint32_t u32_num = 0;
    uint16_t u16_value_len = 0;
    uint16_t u16_key_len = 0;
    uint8_t u8_type = 0;
    int i_num_loop = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL ||p_key == NULL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 77);
    /* key-value个数 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_num, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if ((int)u32_num > bytebuff_remaining(p_st_data))
        return FR_FAIL;

    bytebuff_skip(p_st_data, 1);
    for (; i_num_loop < (int)u32_num; i_num_loop++)
    {
        /* key值长度 */
        i_ret = bytebuff_get_short(p_st_data, 2, &u16_key_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            goto err;

        p_map_key = (char *)frmalloc(u16_key_len + 1);
        if (p_map_key == NULL)
            goto err;
        memset(p_map_key, 0x00, u16_key_len + 1);

        i_ret = bytebuff_get_bytes(p_st_data, p_map_key, u16_key_len);
        if (i_ret == FR_FAIL)
            goto err;

        /* 判断value类型 */
        i_ret = bytebuff_get_char(p_st_data, &u8_type);
        if (i_ret == FR_FAIL)
            goto err;

        memset(arr_key, 0x00, sizeof(arr_key));
        snprintf(arr_key, sizeof(arr_key), "%s.%s", p_key, p_map_key);

        /* 字符串类型 */
        if (u8_type == '\x74')
        {
            /* value长度 */
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_value_len, BYTE_BIG_ENDIAN);
            if (i_ret == FR_FAIL)
                goto err;

            p_map_value = (char *)frmalloc(u16_value_len + 1);
            if (p_map_value == NULL)
                goto err;
            memset(p_map_value, 0x00, u16_value_len + 1);

            /* value值 */
            i_ret = bytebuff_get_bytes(p_st_data, p_map_value, u16_value_len);
            if (i_ret == FR_FAIL)
                goto err;

            /* key-value上报 */
            i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_map_value);
            if (i_ret == FR_FAIL)
                goto err;
            frfree(p_map_value);
            p_map_value = NULL;
        }
        else if (u8_type == '\x75') /* bytes类型 */
        {
            bytebuff_skip(p_st_data, 20);
            /* bytes长度 */
            i_ret = bytebuff_get_short(p_st_data, 2, &u16_value_len, BYTE_BIG_ENDIAN);
            if (i_ret == FR_FAIL)
                goto err;

            p_map_value = (char *)frmalloc(u16_value_len + 1);
            if (p_map_value == NULL)
                goto err;
            memset(p_map_value, 0x00, u16_value_len + 1);

            i_ret = bytebuff_get_bytes(p_st_data, p_map_value, u16_value_len);
            if (i_ret == FR_FAIL)
                goto err;

            /* key-value上报 */
            i_ret = frreport_body_l7_add_bin(p_st_body_data, arr_key, p_map_value, u16_value_len);
            if (i_ret == FR_FAIL)
                goto err;

            frfree(p_map_value);
            p_map_value = NULL;
        }
        else if (u8_type == '\x73') /* 以外 */
        {
            /* 取得value并上报 */
            i_ret = __tonglinkq_analysis_map_getvalue(p_st_body_data, p_st_data, arr_key);
            if (i_ret == FR_FAIL)
                goto err;
        }

        bytebuff_skip(p_st_data, 1);
        frfree(p_map_key);
        p_map_key = NULL;
    }

    return FR_SUCC;

err:
    if (p_map_key)
        frfree(p_map_key);
    if (p_map_value)
        frfree(p_map_value);

    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS跳过属性
*  ARGS     :  p_st_data(消息数据)
*           :  p_u32_type(message类型)
*           :  p_u32_out_len(属性长度)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_skip_option_get_type(Frbyte_Packet *p_st_data, uint32_t *p_u32_type, uint32_t *p_u32_out_len)
{
    char *p_data = NULL;
    char arr_value[16];
    uint32_t u32_name_len = 0;
    uint32_t u32_opt_len = 0;
    uint8_t u8_type = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    *p_u32_out_len = 0;
    /* 属性名长度 */
    if (bytebuff_get_int(p_st_data, 4, &u32_name_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;
    *p_u32_out_len += 4;

    p_data = (char *)frmalloc(u32_name_len + 1);
    if (p_data == NULL)
        return FR_FAIL;
    memset(p_data, 0x00, u32_name_len + 1);

    /* 属性名 */
    if (bytebuff_get_bytes(p_st_data, p_data, u32_name_len) == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }
    *p_u32_out_len += u32_name_len;

    /* value类型 */
    if (bytebuff_get_char(p_st_data, &u8_type) == FR_FAIL)
        return FR_FAIL;
    *p_u32_out_len += 1;

    switch (u8_type)
    {
        case 'I':
            if (bytebuff_get_int(p_st_data, 4, &u32_opt_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }
            *p_u32_out_len += 4;

            if (u32_name_len == strlen("JMS_TONG_MessageType") && strcmp(p_data, "JMS_TONG_MessageType") == 0)
            {
                memset(arr_value, 0x00, sizeof(arr_value));
                if (bytebuff_get_bytes(p_st_data, arr_value, u32_opt_len) == FR_FAIL)
                {
                    frfree(p_data);
                    return FR_FAIL;
                }

                *p_u32_type = atoi(arr_value);
                *p_u32_out_len += u32_opt_len;
            }
            else
            {
                bytebuff_skip(p_st_data, u32_opt_len);
                *p_u32_out_len += u32_opt_len;
            }
            frfree(p_data);
            break;
        default:
            frfree(p_data);
            if (bytebuff_get_int(p_st_data, 4, &u32_opt_len, BYTE_BIG_ENDIAN) == FR_FAIL)
                return FR_FAIL;
            *p_u32_out_len += 4;
            bytebuff_skip(p_st_data, u32_opt_len);
            *p_u32_out_len += u32_opt_len;
            break;
    }

    return FR_SUCC;
}


/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS消息解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_jms_data(Frbyte_Packet *p_st_data
                                          , Frreport_body_data *p_st_body_data
                                          , unsigned int u32_data_len
                                          , int i_req_resp
                                          , int i_is_pub
                                          , int i_size)
{
    char *p_data = NULL;
    char arr_key[64];
    char arr_msgtype_key[64];
    char arr_key_tmp[64];
    char arr_msgtype_key_tmp[64];
    char arr_tlq[5];
    uint32_t u32_msgtype = 0;
    uint32_t u32_opt_num = 0;
    uint32_t u32_loop = 0;
    uint32_t u32_opt_len = 0;
    uint32_t u32_out_len = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, "TLQ", 3, &i_index) == FR_FAIL)
        return FR_FAIL;

    /* 从[\0TLQ]开始计算长度 */
    bytebuff_setPosition(p_st_data, i_index + 3);

    if (bytebuff_get_int(p_st_data, 4, &u32_opt_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 4);
    u32_opt_len -= 12;

    /* 属性个数 */
    if (bytebuff_get_int(p_st_data, 4, &u32_opt_num, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;
    u32_opt_len -= 4;

    for (; u32_loop < u32_opt_num; u32_loop++)
    {
        /* 跳过属性并取得message类型 */
        if (__tonglinkq_skip_option_get_type(p_st_data, &u32_msgtype, &u32_out_len) == FR_FAIL)
            return FR_FAIL;

        if (u32_opt_len >= u32_out_len)
            u32_opt_len -= u32_out_len;
        else
            return FR_FAIL;
    }

    if (u32_opt_len > 0)
        bytebuff_skip(p_st_data, u32_opt_len);

    memset(arr_key, 0x00, sizeof(arr_key));
    memset(arr_msgtype_key, 0x00, sizeof(arr_msgtype_key));

    if (i_req_resp == TLQ_REQUEST)
    {
        snprintf(arr_key, sizeof(arr_key), "%s", MQ_MESSAGE_REQ);
        snprintf(arr_msgtype_key, sizeof(arr_msgtype_key), "%s", APM_REPORT_KEY_REQ);
    }
    else
    {
        snprintf(arr_key, sizeof(arr_key), "%s", MQ_MESSAGE_NOTIFY);
        snprintf(arr_msgtype_key, sizeof(arr_msgtype_key), "%s", APM_REPORT_KEY_NOTIFY);
    }

    switch (u32_msgtype)
    {
        case TLQ_JMS_DATA_TYPE_TEXT:
            /* 消息内容 */
            p_data = (char *)frmalloc(u32_data_len + 1);
            if (p_data == NULL)
                return FR_FAIL;
            memset(p_data, 0x00, u32_data_len + 1);

            i_ret = bytebuff_get_bytes(p_st_data, p_data, u32_data_len);
            if (i_ret == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }

            if (i_size == 0)
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s", arr_msgtype_key, MQ_MESSAGE_TYPE);
            else
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s.%d", arr_msgtype_key, MQ_MESSAGE_TYPE, i_size);
            /* message_type上报 */
            if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype_key_tmp, TLQ_MSG_TYPE_TEXT) == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }

            if (i_size == 0)
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.%s", arr_msgtype_key, TLQ_REPORT_MQ_MSG, TLQ_MESSAGE_TYPE_TEXT);
            else
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.%s.%d", arr_msgtype_key, TLQ_REPORT_MQ_MSG, TLQ_MESSAGE_TYPE_TEXT, i_size);

            /* 消息上报 */
            i_ret = FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, arr_key_tmp, p_data);
            frfree(p_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

//            bytebuff_skip(p_st_data, u32_data_len);
            break;
        case TLQ_JMS_DATA_TYPE_BYTE:
        case TLQ_JMS_DATA_TYPE_STREAM:
        case TLQ_JMS_DATA_TYPE_OBJECT:
            if (i_size == 0)
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s", arr_msgtype_key, MQ_MESSAGE_TYPE);
            else
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s.%d", arr_msgtype_key, MQ_MESSAGE_TYPE, i_size);
            /* message_type上报 */
            if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype_key_tmp, TLQ_MSG_TYPE_OBJ) == FR_FAIL)
                return FR_FAIL;

            if (i_size == 0)
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.%s", arr_msgtype_key, TLQ_REPORT_MQ_MSG, TLQ_MESSAGE_TYPE_BIN);
            else
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.%s.%d", arr_msgtype_key, TLQ_REPORT_MQ_MSG, TLQ_MESSAGE_TYPE_BIN, i_size);
            /* 消息上报 */
            p_data = (char *)frmalloc(u32_data_len);
            if(p_data == NULL)
                return FR_FAIL;

            i_ret = bytebuff_get_bytes(p_st_data, p_data, u32_data_len);
            if(i_ret == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }

            i_ret = frreport_body_l7_add_bin(p_st_body_data, arr_key_tmp, p_data, u32_data_len);
            if (i_ret == FR_FAIL)
            {
                frfree(p_data);
                return FR_FAIL;
            }

            frfree(p_data);
            break;
        case TLQ_JMS_DATA_TYPE_MAP:
            if (i_size == 0)
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s", arr_msgtype_key, MQ_MESSAGE_TYPE);
            else
                snprintf(arr_msgtype_key_tmp, sizeof(arr_msgtype_key_tmp), "%s.%s.%d", arr_msgtype_key, MQ_MESSAGE_TYPE, i_size);
            /* message_type上报 */
            if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype_key_tmp, TLQ_MSG_TYPE_MAP) == FR_FAIL)
                return FR_FAIL;

            if (i_size == 0)
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.map", arr_msgtype_key, TLQ_REPORT_MQ_MSG);
            else
                snprintf(arr_key_tmp, sizeof(arr_key_tmp), "%s.%s.map.%d", arr_msgtype_key, TLQ_REPORT_MQ_MSG, i_size);

            i_ret = __tonglinkq_analysis_map(p_st_data, p_st_body_data, arr_key_tmp);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;

        default:
            break;
    }
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS消息解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_jms_msg(L7session_tonglinkq_private *p_st_private
                                          , Frbyte_Packet *p_st_data
                                          , Frreport_body_data *p_st_body_data
                                          , int i_req_resp)
{
    Tonglinkq_frbyte_resp *p_st_resp = NULL;
    Tonglinkq_L7session *p_st_L7_session = NULL;
    char arr_tmp[2];
//    char arr_size[64];
    char arr_priority[64];
    uint16_t u16_len = 0;
    uint32_t u32_data_len = 0;
    int i_size = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_data == NULL || p_st_body_data == NULL
        || p_st_private->p_st_L7_session == NULL)
        return FR_FAIL;

    if (i_req_resp == TLQ_RESPONSE)
        p_st_resp = p_st_private->p_st_resp;

    if (p_st_resp)
        i_size = p_st_resp->i_msg_size;

    p_st_L7_session = p_st_private->p_st_L7_session;
    /* 请求时上报, 响应时在message ack中上报 */
    if (p_st_L7_session->p_queue)
    {
        if (i_req_resp == TLQ_REQUEST)
        {
            if (p_st_private->i_istopic)
                i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_TOPIC, p_st_L7_session->p_queue);
            else
                i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_REQUEST_QUEUE, p_st_L7_session->p_queue);
        }

        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    while (1)
    {
        i_size++;
        if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, "TLQ", 3, &i_index) == FR_FAIL)
            break;

        /* 优先级 */
        memset(arr_tmp, 0x00, sizeof(arr_tmp));
        i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 1);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (i_req_resp == TLQ_REQUEST)
            snprintf(arr_priority, sizeof(arr_priority), "%s", MQ_PRIORITY_REQ);
        else
            snprintf(arr_priority, sizeof(arr_priority), "%s.%d", MQ_PRIORITY_NOTIFY, i_size);
            //snprintf(arr_priority, sizeof(arr_priority), "%s.%d", MQ_PRIORITY_RESP, i_size);

        i_ret = frreport_body_l7_add_int(p_st_body_data, arr_priority, *arr_tmp);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        bytebuff_setPosition(p_st_data, i_index - 5);
        /* 消息长度 */
        i_ret = bytebuff_get_int(p_st_data, 4, &u32_data_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        /* 消息长度大于100M */
        if (u32_data_len > TLQ_LEN_M*100)
            return FR_FAIL;

        bytebuff_skip(p_st_data, 1);
        if (bytebuff_remaining(p_st_data) < (int)u32_data_len)
            return APM_L7_ANALYZE_TODO;

        if (i_req_resp == TLQ_REQUEST)
            i_ret = __tonglinkq_analysis_jms_data(p_st_data, p_st_body_data, u32_data_len, i_req_resp, TLQ_MSG_PTP, 0);
        else
            i_ret = __tonglinkq_analysis_jms_data(p_st_data, p_st_body_data, u32_data_len, i_req_resp, TLQ_MSG_PTP, i_size);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (bytebuff_remaining(p_st_data) == 0)
            break;

        i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
        if (i_ret == FR_FAIL)
            return FR_FAIL;

        if (bytebuff_remaining(p_st_data) < u16_len-2)
            return APM_L7_ANALYZE_TODO;

        bytebuff_skip(p_st_data, 2);
    }

    if (i_req_resp == TLQ_RESPONSE)
        p_st_resp->i_msg_size = i_size;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS文件解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_jms_file(L7session_tonglinkq_private *p_st_private
                                          , Frbyte_Packet *p_st_data
                                          , Frreport_body_data *p_st_body_data
                                          , int i_req_resp)
{
    Tonglinkq_L7session *p_st_L7session = NULL;
    char *p_file = NULL;
    char arr_queue[49];
    char arr_title[64];
    char arr_key[64];
    uint16_t u16_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_L7_session == NULL
        || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_L7session = p_st_private->p_st_L7_session;

    memset(arr_key, 0x00, sizeof(arr_key));
    if (i_req_resp == TLQ_REQUEST)
        snprintf(arr_key, sizeof(arr_key), "request.%s", MQ_MESSAGE_TYPE);
    else
        snprintf(arr_key, sizeof(arr_key), "response.%s", MQ_MESSAGE_TYPE);
    /* 消息类型上报 */
    i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, TLQ_MSG_TYPE_FILE);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (i_req_resp == TLQ_REQUEST)
        bytebuff_skip(p_st_data, 22);
    else
        bytebuff_skip(p_st_data, 13);

    /* 队列名长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    memset(arr_queue, 0x00, sizeof(arr_queue));
    /* 队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, arr_queue, u16_len);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    /* 添加到session */
    if (p_st_L7session->p_queue == NULL)
    {
        p_st_L7session->p_queue = frstrdup(arr_queue);
        if (p_st_L7session->p_queue == NULL)
            return FR_FAIL;
    }

    memset(arr_title, 0x00, sizeof(arr_title));
    if (i_req_resp == TLQ_REQUEST)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_L7session->p_queue);
    }
    else
    {
        snprintf(arr_title, sizeof(arr_title), "GET %s", p_st_L7session->p_queue);
    }

    /* 设置title */
    if (p_st_L7session->p_title)
        frfree(p_st_L7session->p_title);
    p_st_L7session->p_title = frstrdup(arr_title);
    if (p_st_L7session->p_title == NULL)
        return FR_FAIL;

    if (i_req_resp == TLQ_REQUEST)
        bytebuff_skip(p_st_data, 7);
    else
        bytebuff_skip(p_st_data, 18);

    /* MsgId长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, u16_len);

    /* 文件路径长度 */
    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if ((int)u16_len > bytebuff_remaining(p_st_data))
        return FR_FAIL;

    p_file = (char *)frmalloc(u16_len + 1);
    if (p_file == NULL)
        return FR_FAIL;
    memset(p_file, 0x00, u16_len + 1);

    /* 文件路径 */
    i_ret = bytebuff_get_bytes(p_st_data, p_file, u16_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_file);
        return FR_FAIL;
    }

    memset(arr_key, 0x00, sizeof(arr_key));
    if (i_req_resp == TLQ_REQUEST)
        snprintf(arr_key, sizeof(arr_key), "%s.%s", MQ_MESSAGE_REQ, TLQ_MSG_TYPE_FILE);
    else
        snprintf(arr_key, sizeof(arr_key), "%s.%s", MQ_MESSAGE_RESP, TLQ_MSG_TYPE_FILE);

    if (i_req_resp == TLQ_REQUEST)
    {
        p_file[u16_len-1] = '\0';
        /* 文件名(路径)上报 */
        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_file+1);
    }
    else
    {
        /* 文件名(路径)上报 */
        i_ret = frreport_body_l7_add_str(p_st_body_data, arr_key, p_file);
    }
    frfree(p_file);
    if (i_ret == FR_FAIL)
    {
        frfree(p_file);
        return FR_FAIL;
    }

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS传输信息解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_data(数据)
            :  p_st_body_data(上报数据)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_jms_transfer(L7session_tonglinkq_private *p_st_private
                                              , Frbyte_Packet *p_st_data
                                              , Frreport_body_data *p_st_body_data)
{
    Tonglinkq_L7session *p_st_L7session = NULL;
    char *p_queue = NULL;
    uint32_t u32_len = 0;
    int i_index = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_L7_session == NULL
        || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_L7session = p_st_private->p_st_L7_session;

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), 0, "TLQ", 3, &i_index) == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), bytebuff_remaining(p_st_data)
        , TLQ_TMQITOPIC_PUBQUE, strlen(TLQ_TMQITOPIC_PUBQUE), &i_index) == FR_SUCC)
        p_st_private->i_istopic = TLQ_YES;
    else
        p_st_private->i_istopic = TLQ_NO;

    if (bytebuff_memstr(p_st_data, bytebuff_getPosition(p_st_data), bytebuff_remaining(p_st_data)
      , TLQ_TMQIDEST_QUEUE,strlen (TLQ_TMQIDEST_QUEUE), &i_index) == FR_FAIL)
        return FR_FAIL;

    bytebuff_setPosition(p_st_data, i_index+strlen (TLQ_TMQIDEST_QUEUE)+1);

    /* 取队列名长度 */
    i_ret = bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if ((int)u32_len > bytebuff_remaining(p_st_data))
        return FR_FAIL;

    p_queue = (char *)frmalloc(u32_len + 1);
    if (p_queue == NULL)
        return FR_FAIL;

    memset(p_queue, 0x00, u32_len + 1);
    /* 队列名 */
    i_ret = bytebuff_get_bytes(p_st_data, p_queue, u32_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_queue);
        return FR_FAIL;
    }

    /* 添加到session信息 */
    if (p_st_L7session->p_queue == NULL)
    {
        p_st_L7session->p_queue = frstrdup(p_queue);
        if (p_st_L7session->p_queue == NULL)
        {
            frfree(p_queue);
            return FR_FAIL;
        }
    }
    frfree(p_queue);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q JMS数据解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
FR_STATIC int __tonglinkq_analysis_jms(L7session_tonglinkq_private *p_st_private
                                     , Frbyte_Packet *p_st_data
                                     , Frreport_body_data *p_st_body_data
                                     , int i_req_resp
                                     , int *i_need_report)
{
    Tonglinkq_L7session *p_st_L7session = NULL;
    Tonglinkq_frbyte_resp *p_st_resp = NULL;
    Tonglinkq_frbyte_req *p_st_req = NULL;
    char arr_tmp[2];
    char arr_title[64];
    uint8_t u8_flag = 0;
    uint8_t u8_code = 0;
    uint16_t u16_len = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_private->p_st_L7_session == NULL
        || p_st_data == NULL || p_st_body_data == NULL)
        return FR_FAIL;

    p_st_L7session = p_st_private->p_st_L7_session;

    i_ret = bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < u16_len-2)
        return APM_L7_ANALYZE_TODO;

    bytebuff_skip(p_st_data, 1);
    memset(arr_tmp, 0x00, sizeof(arr_tmp));
    i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    switch (*arr_tmp)
    {
        case '\x17':  //message
            memset(arr_title, 0x00, sizeof(arr_title));
            /* method 上报 */
            if (i_req_resp == TLQ_REQUEST)
            {
                i_ret = frreport_body_l7_add_str(p_st_body_data, MQ_METHOD_REQ, "PUT");
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                if (p_st_L7session->p_queue != NULL)
                    /* 设置title */
                    snprintf(arr_title, sizeof(arr_title), "PUT %s", p_st_L7session->p_queue);

                i_ret = __tonglinkq_analysis_jms_msg(p_st_private, p_st_data, p_st_body_data, i_req_resp);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
            }
            else
            {
                p_st_resp = p_st_private->p_st_resp;

                if (p_st_L7session->p_queue != NULL)
                    /* 设置title */
                    snprintf(arr_title, sizeof(arr_title), "NOTIFY %s", p_st_L7session->p_queue);

                if (p_st_private->i_istopic == TLQ_YES)
                    p_st_private->i_isnotify = TLQ_YES;
                else
                {
                    if (p_st_resp)
                        p_st_resp->i_message_ack = 1;
                }

                i_ret = __tonglinkq_analysis_jms_msg(p_st_private, p_st_data, p_st_body_data, i_req_resp);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
            }

            /* 设置title */
            if (p_st_L7session->p_title)
                frfree(p_st_L7session->p_title);
            p_st_L7session->p_title = frstrdup(arr_title);
            if (p_st_L7session->p_title == NULL)
                return FR_FAIL;

            *i_need_report = TLQ_YES;
            break;
        case '\x20':  //dataResponse
            if (i_req_resp == TLQ_RESPONSE)
            {
                bytebuff_skip(p_st_data, 6);
                memset(arr_tmp, 0x00, sizeof(arr_tmp));
                i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 1);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                if (*arr_tmp == '\x17')
                    *i_need_report = TLQ_YES;
                else
                    *i_need_report = TLQ_NO;
            }
            else
                *i_need_report = TLQ_NO;
            break;
        case '\x21':  //dataArrayResponse
            if (i_req_resp == TLQ_RESPONSE)
            {
                bytebuff_skip(p_st_data, 6);
                memset(arr_tmp, 0x00, sizeof(arr_tmp));
                i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 1);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;

                if (*arr_tmp == '\0')
                    *i_need_report = TLQ_YES;
                else
                    *i_need_report = TLQ_NO;
            }
            else
                *i_need_report = TLQ_NO;
            break;

        case '\x05':  //ComsumerInfo
            if (!p_st_private->i_istopic)
            {
                *i_need_report = TLQ_NO;
                break;
            }

            /* 取响应码 */
            if (bytebuff_peek_char(p_st_data, &u8_flag) == FR_FAIL)
                return FR_FAIL;
            if (u8_flag == 1)
                bytebuff_skip(p_st_data, 5);
            else if (u8_flag == 2)
                bytebuff_skip(p_st_data, 6);

            if (bytebuff_get_char(p_st_data, &u8_code) == FR_FAIL)
                return FR_FAIL;
            p_st_private->i_resp_code = u8_code;

            /* SUB */
            i_ret = __tonglinkq_analysis_sub(p_st_body_data, p_st_L7session, p_st_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;

            p_st_req = p_st_private->p_st_req;
            if (p_st_req)
                p_st_req->i_pubsub_flag = TLQ_MSG_SUB;
            *i_need_report = TLQ_YES;
            break;
        case '\x52':  //filemessage
            i_ret = __tonglinkq_analysis_jms_file(p_st_private, p_st_data, p_st_body_data, i_req_resp);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            break;
        case '\x08':  //DestationInfo
            /* jms 传输信息 */
            i_ret = __tonglinkq_analysis_jms_transfer(p_st_private, p_st_data, p_st_body_data);
            if (i_ret == FR_FAIL)
                return FR_FAIL;
            *i_need_report = TLQ_NO;
            break;
        case '\x16':  //message ack
            p_st_resp = p_st_private->p_st_resp;
            if (p_st_resp == NULL)
                return FR_FAIL;
            p_st_resp->i_message_ack = 2;
            *i_need_report = TLQ_YES;
            break;
        case '\x1e':
            /* 取响应码 */
            if (bytebuff_peek_char(p_st_data, &u8_flag) == FR_FAIL)
                return FR_FAIL;
            if (u8_flag == 1)
                bytebuff_skip(p_st_data, 5);
            else if (u8_flag == 2)
                bytebuff_skip(p_st_data, 6);

            if (bytebuff_get_char(p_st_data, &u8_code) == FR_FAIL)
                return FR_FAIL;

            if (u8_code == p_st_private->i_resp_code)
                *i_need_report = TLQ_YES;
            else
                *i_need_report = TLQ_NO;

            p_st_private->i_resp_code = 0;
            break;
        default:
            *i_need_report = TLQ_NO;
            break;
    }

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  TongLINK/Q数据解析
*  ARGS     :  p_st_private(TongLINK/Q私有数据)
            :  p_st_body_data(上报数据)
            :  i_req_resp(request或response的flag)
*  RTN      :  FR_FAIL                  失败
*           :  FR_SUCC                  成功
*  NOTE     :
*******************************************************************************/
int tonglinkq_analysis_data(L7session_tonglinkq_private *p_st_private
                          , Frreport_body_data *p_st_body_data
                          , int i_req_resp
                          , int *i_need_report)
{
    Frbyte_Packet *p_st_data = NULL;
    Frbyte_Packet *p_st_msg = NULL;
    Frreport_body_data *p_st_body_data_req = NULL;
    Tonglinkq_L7session *p_st_L7session = NULL;
    L4_transaction st_l4_trans_req;
    char arr_tmp[2];
    char arr_version[3];
    char arr_tongjms[9];
    char arr_server[64];
    char *p_title = NULL;
    unsigned long ul_seq = 0;
    int i_responserequired = 0;
    int i_file_flag = 0;
    int i_ret = 0;

    if (p_st_private == NULL || p_st_body_data == NULL || p_st_private->p_st_L7_session == NULL)
        return FR_FAIL;

    p_st_L7session = p_st_private->p_st_L7_session;

    if (i_req_resp == TLQ_REQUEST)
    {
        if (p_st_private->p_st_req)
            p_st_data = p_st_private->p_st_req->p_st_data_req;
        else
            return FR_FAIL;
        p_st_msg = p_st_private->p_st_req->p_st_msg;
    }
    else
    {
        if (p_st_private->p_st_resp)
            p_st_data = p_st_private->p_st_resp->p_st_data_resp;
        else
            return FR_FAIL;

        i_ret = frreport_body_l7_add_int(p_st_body_data, "response.code", 0);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    memset(arr_tongjms, 0x00, sizeof(arr_tongjms));
    if (bytebuff_remaining(p_st_data) > 18)
    {
        /* TONG_JMS */
        i_ret = bytebuff_get_bytes_at(p_st_data, 10, 8, arr_tongjms);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    /* JMS解析 */
    if (strncmp(arr_tongjms, TLQ_TONG_JMS, 8) == 0)
    {
        p_st_private->i_jms_flag = TLQ_YES;
        *i_need_report = TLQ_NO;
        return FR_SUCC;
    }

    if (p_st_private->i_jms_flag == TLQ_YES)
    {
        /* 添加服务名到session */
        if (p_st_L7session->p_server == NULL)
        {
            memset(arr_server, 0x00, sizeof(arr_server));
            strcpy(arr_server, "tonglinkq");
            p_st_L7session->p_server = frstrdup(arr_server);
            if (p_st_L7session->p_server == NULL)
                return FR_FAIL;
        }
        i_ret = __tonglinkq_analysis_jms(p_st_private, p_st_data, p_st_body_data, i_req_resp, i_need_report);
        return i_ret;
    }

    bytebuff_skip(p_st_data, 1);
    memset(arr_tmp, 0x00, sizeof(arr_tmp));
    i_ret = bytebuff_get_bytes(p_st_data, arr_tmp, 1);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (*arr_tmp != '\x05' && *arr_tmp != '\x06')
    {
        *i_need_report = TLQ_NO;
        bytebuff_skip(p_st_data, bytebuff_remaining(p_st_data));
        if (i_req_resp == TLQ_RESPONSE)
            p_st_private->p_st_resp->i_asyn_flag = 0;
        return FR_SUCC;
    }

    *i_need_report = TLQ_YES;

    /* 判断是不是文件内容 */
    if (*arr_tmp == '\x06' && i_req_resp == TLQ_REQUEST)
    {
        /* 跳过头部 */
        bytebuff_skip(p_st_data, TLQ_HEAD_LEN - 2);
        if (i_ret == FR_FAIL)
           return FR_FAIL;

        memset(arr_version, 0x00, sizeof(arr_version));
        i_ret = bytebuff_peek_bytes(p_st_data, arr_version, 2);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
        /* 是文件内容 */
        if (*arr_version != gi_version && arr_version[1] != 1)
        {
            i_file_flag = 1;
        }

        bytebuff_rewind(p_st_data);
        bytebuff_skip(p_st_data, 2);
    }

    /* 不是上次的消息内容才做头部解析 */
    if (p_st_msg == NULL && i_file_flag != 1)
    {
        i_ret = __tonglinkq_analysis_head(p_st_body_data, p_st_L7session, p_st_data, i_req_resp);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    /* 本次数据是上次消息内容剩余部分 */
    else if (p_st_msg != NULL)
    {
        bytebuff_skip(p_st_data, 302);/* 2+302+232=536 */
    }
    /* 本次数据是File文件传输的文件内容 */
    else if (i_file_flag == 1)
    {
        i_ret = __tonglinkq_analysis_file_data(p_st_private, p_st_body_data, p_st_data);
        return i_ret;
    }

    i_ret = __tonglinkq_get_msgid(p_st_private, p_st_data, i_req_resp);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (i_req_resp == TLQ_REQUEST)
    {
        p_st_private->p_st_req->i_responserequired = 1;
        bytebuff_skip(p_st_data, 139);
        i_ret = __tonglinkq_analysis_msginfo(p_st_private, p_st_body_data, p_st_data, i_need_report);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }
    else
    {
        p_st_private->p_st_resp->i_asyn_flag = 1;
        /* 取对应的request数据 */
        p_st_body_data_req = tonglinkq_get_req_node(p_st_private, &ul_seq
                                                  , &i_responserequired, &st_l4_trans_req, &p_title);
        if (p_st_body_data_req == NULL)
            *i_need_report = TLQ_NO;
        else
        {
            frreport_body_free(&p_st_body_data_req);
        }
    }

    return i_ret;
}
